package com.mc.aop;

import com.alibaba.fastjson.JSONObject;
import com.mc.annotation.Log;
import com.mc.mapper.model.SysLog;
import com.mc.service.log.ILogService;
import com.mc.util.WebUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/***
 * @ClassName LogAop
 * @Description 日志AOP切面
 * @Author CC
 * @Date: 2019/11/910:10
 * @Version 1.0
 */
@Aspect
@Component
public class LogAop {
    private static final Logger log = LoggerFactory.getLogger(LogAop.class);

    @Autowired
    ILogService logService;
    //保证线程安全
    ThreadLocal<Long> startTime = new ThreadLocal<>();
    ThreadLocal<Long> logId = new ThreadLocal<>();

    @Pointcut("@annotation(com.mc.annotation.Log)")
    public void logCut() {
    }

    @Before("logCut()")
    public void before(JoinPoint joinPoint) throws Throwable {
        startTime.set(System.currentTimeMillis());
        saveLogs(joinPoint);
    }


    @AfterReturning(returning = "returnResult", pointcut = "logCut()")
    public void afterReturn(Object returnResult) {
        try {
            updateLog(returnResult);
        } catch (Exception e) {
            log.warn("LogAop异常>>>>>>" + e.getMessage());
        }

    }


    @AfterThrowing(pointcut = "logCut()", throwing = "e")
    public void doAfterThrow(Throwable e) {
        try {
            updateLog(e);
        } catch (Exception el) {
            log.warn("LogAop异常>>>>>>" + el.getMessage());
        }
    }

    private void saveLogs(JoinPoint joinPoint) throws Exception {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Log annotation = method.getAnnotation(Log.class);
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        Object[] args = joinPoint.getArgs();
        HttpServletRequest request = WebUtil.getRequest();
        SysLog sysLog = new SysLog();
        sysLog.setCreateTime(new Date());
        sysLog.setMethod(className + "." + methodName + "()");
        sysLog.setOperation(annotation != null ? annotation.value() : "");
        sysLog.setParams(args != null && args.length > 0 ? JSONObject.toJSONString(args) : null);
        sysLog.setIp(WebUtil.getRemoteIP(request));
        sysLog.setUserName("test");

//        logService.saveLog(sysLog);
        Long id = sysLog.getId();
        logId.set(id);
    }

    private void updateLog(Object returnResult) {
        SysLog sysLog = new SysLog();
        sysLog.setResult(JSONObject.toJSONString(returnResult));
        sysLog.setId(logId.get());
        sysLog.setResTime(System.currentTimeMillis() - startTime.get());
//        logService.update(sysLog);
    }


}
